home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / LAN / LANMONIT.M2 < prev    next >
Encoding:
Text File  |  1991-08-18  |  37.0 KB  |  3 lines

  1. ⓪ MODULE LANMonitor; (*$H+,Z+,R-*)⓪ ⓪ (*⓪ NOTES⓪ -----⓪ - Testen auch ohne Interrupts - nur Polling!⓪ - Die CRC-Prüfung scheint nicht zu klappen. Zumindest wird kein Fehler angezeigt,⓪"wenn beim empf. Dataframe das 1.Byte fehlt.⓪"-> Evtl. wird overrun gelmeldet und nicht erkannt?⓪ - Wenn 'excessCollsns' gemeldet wird, kann das auch heißen, daß⓪"der Partner überhaupt nicht geantwortet hat (also kein CTS auf's RTS⓪"gesandt hat).⓪ - oft passiert es, daß das CTS zu spät kommt. Dann wird in 'GetFrame'⓪"'fAdrInUse' gesetzt, weil man annimmt, daß jemand anderes auf ein RTS⓪"geantwortet hat (denn 'fCTSexpected ist schon FALSE).⓪"Das ist eigentlich OK, nur daß das *erwartete* CTS offenbar dann zu spät kam.⓪ - seltsamerweise klappt beim TransmitPacket immer der erste RTS nicht.⓪"Es kommt dann kein CTS? Bei weiteren RTS klappt's dafür immer.⓪ *)⓪ ⓪ (*⓪ IMPORT TOSDebug;⓪ *)⓪ ⓪ IMPORT SYSTEM;⓪ FROM SYSTEM IMPORT ASSEMBLER, ADR, BYTE;⓪ ⓪ IMPORT MOSGlobals, PrgCtrl;⓪ ⓪ IMPORT TOSIO; (*$E MOS *)⓪ IMPORT InOut, FuncStrings, StrConv;⓪ FROM InOut IMPORT WriteLn, Write, WriteCard, ReadCard, ReadLCard, Read,⓪0GotoXY, WritePg, WriteString, WriteHex, WriteLHex,⓪0KeyPressed, Done, WriteNum, WriteLNum;⓪ ⓪ FROM GEMDOS IMPORT Super;⓪ IMPORT VT52; FROM VT52 IMPORT Codes;⓪ FROM Storage IMPORT ALLOCATE;⓪ ⓪ ⓪ CONST NMI_Mask = $0700; (* !!! $0700 *)⓪ ⓪ ⓪ (*****************************************************************************)⓪ ⓪ ⓪ MODULE SCC;⓪ (*$L-*)⓪ ⓪ FROM SYSTEM IMPORT WORD, ADDRESS, ASSEMBLER;⓪ ⓪ IMPORT Super;⓪ FROM PrgCtrl IMPORT TermCarrier, CatchProcessTerm;⓪ FROM MOSGlobals IMPORT MemArea;⓪ ⓪ EXPORT QUALIFIED Reg, SetReg, CTLA;⓪ ⓪ CONST CTLA = $FFFF8C81;⓪ ⓪ PROCEDURE Reg (n: CARDINAL): CARDINAL;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE    SR,-(A7)⓪(MOVE    #$2500,SR⓪(MOVEA.W #CTLA,A1⓪(MOVE.W  -(A3),D0⓪(BEQ     read0⓪(MOVE.B  D0,(A1)          ; SCC A control⓪&read0:⓪(MOVE.B  (A1),D0⓪(MOVE    (A7)+,SR⓪$END;⓪"END Reg;⓪ ⓪ PROCEDURE SetReg (no, value: CARDINAL);⓪"BEGIN⓪$ASSEMBLER⓪(MOVE    SR,-(A7)⓪(MOVE    #$2500,SR⓪(MOVEA.W #CTLA,A1⓪(MOVE.W  -(A3),D1        ; value⓪(MOVE.W  -(A3),D0        ; no⓪(BEQ     write0⓪(MOVE.B  D0,(A1)         ; SCC A control⓪&write0:⓪(MOVE.B  D1,(A1)⓪(MOVE    (A7)+,SR⓪$END;⓪"END SetReg;⓪ ⓪ (*$L=*)⓪ ⓪ (****** Vorsicht: ab hier $L+ ******)⓪ ⓪ PROCEDURE term;⓪"VAR ssp: LONGCARD;⓪"BEGIN⓪$ssp:= Super (0);⓪$SetReg (9, $C0);⓪$ssp:= Super (ssp)⓪"END term;⓪ ⓪ VAR carrier: TermCarrier;⓪ ⓪ BEGIN⓪"CatchProcessTerm (carrier, term, MemArea{NIL,0});⓪ END (* MODULE *) SCC;⓪ ⓪ (*****************************************************************************)⓪ ⓪ MODULE ALAP;⓪ ⓪ FROM SYSTEM IMPORT ADR, ASSEMBLER, BITNUM, BYTE, WORD, LONGWORD, ADDRESS, SHIFT;⓪ IMPORT SCC;⓪ FROM SCC IMPORT CTLA;⓪ IMPORT Super, ALLOCATE;⓪ IMPORT NMI_Mask;⓪ ⓪ (* I/O-Routinen für Testausgaben *)⓪ IMPORT InOut;⓪ FROM FuncStrings IMPORT ConcStr;⓪ FROM StrConv IMPORT CardToStr;⓪ ⓪ EXPORT QUALIFIED⓪"WriteFrame, WriteStatus,⓪"Init, TransmitStatus, TransmitPacket, ReceiveFrame, ReceivePacket,⓪"myAddress, fAdrValid, fAdrInUse, FramesReceived, Interrupts,⓪"maxIFGtime, test, NewPacketBuffer, FrameStatus, anAddress, aLAPtype,⓪"packetBuffers, aDataField, lapENQ,⓪"aRxFrame, aTxFrame, aPacket, ptrPacket, maxDataSize, headPacket, tailPacket,⓪"deferCount, collsnCount, DataFramesOut, CTSFramesOut, RTSFramesOut;⓪"⓪ ⓪ ⓪ CONST   minFrameSize = 3;⓪(maxDataSize = 600;⓪(maxFrameSize = maxDataSize+5;⓪(⓪((* alle Zeitwerte sind in µs angegeben *)⓪(bitTime = 5 (* 4.34 *);⓪(byteTime = 39;⓪(IDGslottime = 300;⓪(maxIFGtime = 500; (* 200 ist für ENQ->ACK offenbar zu klein. *)⓪(minIDGtime = 2*maxIFGtime;⓪(⓪(maxDefers = 32;⓪(maxCollsns = 32;⓪(lapENQ = BYTE($81);⓪(lapACK = BYTE($82);⓪(lapRTS = BYTE($84);⓪(lapCTS = BYTE($85);⓪(wksTries = 20;⓪(⓪(rxEnable = $DD;⓪(setRTS   = $62;⓪(txEnable = $6B;⓪ ⓪ TYPE    TransmitStatus = (transmitOK, excessDefers, excessCollsns, dupAddress);⓪(ReceiveStatus = (receiveOK, receiving, nullReceive, frameError);⓪(FrameStatus = (noFrame, lapDATAframe, lapENQframe, lapACKframe,⓪(lapRTSframe, lapCTSframe, badframeCRC, badframeSize, badframeType,⓪(overrunError, underrunError, lostAddress, undefined);⓪(⓪(bitVector = SET OF BITNUM[0..7];⓪(octet = BYTE;⓪(anAddress = octet;⓪(aLAPtype = octet;⓪(aDataField = ARRAY [1..maxDataSize] OF octet;⓪(ptrDataField = POINTER TO aDataField;⓪ ⓪(frameInterpretation = (raw, structured);⓪(aRxFrame = RECORD⓪5CASE :frameInterpretation OF⓪7raw:⓪9rawData: ARRAY [1..maxFrameSize] OF octet|⓪7structured:⓪9dstAddr: anAddress;⓪9srcAddr: anAddress;⓪9lapType: aLAPtype;⓪9dataField: aDataField⓪5END⓪3END;⓪(⓪(aCtrlFrame = RECORD⓪7dstAddr: anAddress;⓪7srcAddr: anAddress;⓪7lapType: aLAPtype;⓪5END;⓪ ⓪(ptrPacket = POINTER TO aPacket;⓪(aPacket = RECORD⓪4status: FrameStatus;⓪4length: [0..maxFrameSize];⓪4next  : ptrPacket;⓪4frame : aRxFrame;⓪4no    : CARDINAL;⓪2END;⓪ ⓪(aTxFrame = RECORD⓪5ctrl: aCtrlFrame;⓪5dataCnt: CARDINAL;⓪5dataPtr: ptrDataField⓪3END;⓪ ⓪ VAR     myAddress: anAddress;⓪(backoff: INTEGER;⓪(fAdrValid: BOOLEAN;⓪(fAdrInUse: BOOLEAN;⓪(fCTSexpected: BOOLEAN;⓪(deferCount, collsnCount: CARDINAL;⓪(DataFramesOut, RTSFramesOut, CTSFramesOut: CARDINAL;⓪(deferHistory, collsnHistory: bitVector;⓪(deferTries, collsnTries, lclbackoff: INTEGER;⓪(RTSframe: aTxFrame;⓪(seed: LONGCARD;⓪(packetBuffers: CARDINAL;⓪(tailPacket: ptrPacket;  (* zeigt aufs älteste gültige Paket *)⓪(headPacket: ptrPacket;  (* zeigt hinter jüngstes Paket *)⓪*(* wenn head = tail, stehen keine neuen Pakete an. *)⓪(⓪(FramesReceived, Interrupts: CARDINAL;⓪(test: BOOLEAN;⓪(⓪(IR_Vector [$360]: PROC;⓪ ⓪ (* -------------------------------------------------- *)⓪ ⓪ PROCEDURE resetRx;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(MOVEA.W #CTLA,A1⓪(; resetRx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #$D0,(A1)       ; disableRx⓪(MOVEQ   #2,D0⓪&flushFIFO:⓪(TST.B   2(A1)⓪(DBRA    D0,flushFIFO⓪(MOVE.B  #$30,(A1)       ; reset error⓪(MOVE.B  #$20,(A1)       ; enable IR on next Rx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #rxEnable,(A1)  ; enableRx⓪$END⓪"END resetRx;⓪"(*$L=*)⓪"⓪ ⓪ CONST  rnda = 1664525;     (* Knuth S.102 Zeile 26 *)⓪'rndc = 117;         (* teilerfremd mit 2^32 für max. Periode 2^32 *)⓪ ⓪ PROCEDURE random;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(; IN: D0.W max-Wert minus 1, OUT: D0.W 0..max-1⓪(MOVE.W  D0,-(A7)⓪(MOVE.L  seed,D0⓪(BNE     isInit⓪(; seek initialisieren⓪(MOVEM.L A0-A2,-(A7)⓪(MOVE    #17,-(A7)⓪(TRAP    #14⓪(ADD.L   D0,seed⓪(TRAP    #14⓪(ADDQ.L  #2,A7⓪(MOVEM.L (A7)+,A0-A2⓪(LSL.L   #8,D0⓪(ADD.L   D0,seed⓪&isInit:⓪(MOVE.L  D0,D1⓪(MOVE.L  D0,D2⓪(SWAP    D2⓪(MOVE.L  D3,-(A7)⓪(MOVE.L  #rnda,D3⓪(MULU    D3,D0⓪(MULU    D3,D2⓪(SWAP    D3⓪(MULU    D3,D1⓪(MOVE.L  (A7)+,D3⓪(SWAP    D1⓪(CLR.W   D1⓪(SWAP    D2⓪(CLR.W   D2⓪(ADD.L   D1,D0⓪(ADD.L   D2,D0⓪(ADDI.L  #rndc,D0⓪(MOVE.L  D0,seed⓪(MOVE.W  (A7)+,D1⓪(BEQ     rtn0⓪(MOVE.W  D0,D2⓪(CLR.W   D0⓪(SWAP    D0⓪(DIVU    D1,D0⓪(MOVE.W  D2,D0⓪(DIVU    D1,D0⓪(SWAP    D0⓪(RTS⓪&rtn0⓪(MOVEQ   #0,D0⓪$END⓪"END random;⓪"(*$L=*)⓪ ⓪ PROCEDURE Wr (REF s: ARRAY OF CHAR);⓪"BEGIN⓪$InOut.WriteString (s);⓪$InOut.WriteLn;⓪"END Wr;⓪ ⓪ PROCEDURE WriteFrame (REF packet: aPacket; no: CARDINAL);⓪"VAR n: CARDINAL;⓪"BEGIN⓪$FOR n:= 1 TO 5 DO⓪&IF n > packet.length THEN⓪(InOut.WriteString ('   ');⓪&ELSE⓪(InOut.WriteHex (LONG (packet.frame.rawData [n]), 3);⓪&END⓪$END;⓪$FOR n:= 6 TO no DO⓪&IF n <= packet.length THEN⓪(InOut.WriteHex (LONG (packet.frame.rawData [n]), 3);⓪(IF (ORD (packet.frame.rawData [n]) >= 32) AND⓪+(ORD (packet.frame.rawData [n]) < 128) THEN⓪*InOut.Write ('/');⓪*InOut.Write (CHAR(packet.frame.rawData [n]));⓪(END⓪&END⓪$END;⓪$InOut.WriteString (' ');⓪"END WriteFrame;⓪ ⓪ PROCEDURE WriteStatus (status: FrameStatus);⓪"BEGIN⓪$CASE status OF⓪&|badframeCRC: InOut.WriteString ('>badframeCRC<')⓪&|badframeSize: InOut.WriteString ('>badframeSize<');⓪&|badframeType: InOut.WriteString ('>badframeType<')⓪&|overrunError: InOut.WriteString ('>overrunError<')⓪&|underrunError: InOut.WriteString ('>underrunError<')⓪&|lostAddress: InOut.WriteString ('>lost address<')⓪&|lapACKframe: InOut.WriteString ('>ACKframe<')⓪&|lapENQframe: InOut.WriteString ('>ENQframe<');⓪&|lapRTSframe: InOut.WriteString ('>RTSframe<');⓪&|lapCTSframe: InOut.WriteString ('>CTSframe<');⓪&|lapDATAframe: InOut.WriteString ('>DATAframe<');⓪&|noFrame: InOut.WriteString ('no frame!');⓪$ELSE⓪&InOut.WriteString ('unknown frame!');⓪$END;⓪"END WriteStatus;⓪ ⓪ (* --------------------------- *)⓪ ⓪ FORWARD AcquireAddress;⓪ FORWARD TransmitPacket;⓪ FORWARD TransmitFrame;⓪ FORWARD ReceiveFrame (VAR packet: ptrPacket): FrameStatus;⓪ FORWARD ReceiveLinkMgmt (VAR packet: ptrPacket): ReceiveStatus;⓪ FORWARD IR_Handler;⓪ FORWARD GetFrame;⓪ ⓪ PROCEDURE NewPacketBuffer;⓪"VAR p, prev, last: ptrPacket; sr: CARDINAL;⓪"BEGIN⓪$ASSEMBLER⓪(MOVE    SR,sr(A6)⓪(MOVE    #$2500,SR⓪$END;⓪$NEW (p);⓪$IF p # NIL THEN⓪&IF packetBuffers = 0 THEN⓪(headPacket:= p;⓪(tailPacket:= p;⓪(last:= p⓪&ELSE⓪(prev:= headPacket;⓪(WHILE prev^.next # tailPacket DO⓪*prev:= prev^.next⓪(END;⓪(last:= prev^.next;⓪(prev^.next:= p⓪&END;⓪&INC (packetBuffers);⓪&WITH p^ DO⓪(next:= last;⓪(status:= undefined;⓪(no:= packetBuffers⓪&END;⓪$END;⓪$ASSEMBLER⓪(MOVE    sr(A6),SR⓪$END;⓪"END NewPacketBuffer;⓪ ⓪ PROCEDURE ResetReceiveBuffer;⓪"BEGIN⓪$tailPacket:= headPacket⓪"END ResetReceiveBuffer;⓪ ⓪ TABLE.W SCCInitData:⓪*$09C0, $0420, $0AE0, $0600, $077E, $0C06, $0D00, $0EC0,⓪*$03D0, $0B70, $0E21, $0560, $0F00, $0108,⓪*$0200 + ADR (IR_Vector) DIV 4, $0908, $0300+rxEnable, 0;⓪ ⓪ (*$L-*)⓪ ⓪ PROCEDURE Init;⓪"(* IN: D0.B: proposed address, 0 if none *)⓪"BEGIN⓪$ASSEMBLER⓪(MOVE.B  D0,myAddress⓪(CLR     backoff⓪(CLR.B   deferHistory⓪(CLR.B   collsnHistory⓪(⓪(JSR     NewPacketBuffer⓪(JSR     NewPacketBuffer⓪(JSR     NewPacketBuffer⓪$⓪(; Init Timer A⓪(MOVEA.W #$FA00,A0⓪(MOVE.B  #$00,$19(A0)    ; TACR: Timer Stop⓪(ANDI.B  #$DF,$13(A0)    ; IMRA: Mask Timer A IR⓪(ORI.B   #$20,$07(A0)    ; IERA: Enable Timer-A Pending Bit⓪(MOVE.B  #$DF,$0B(A0)    ; IPRA: Clear Timer-A Pending Bit⓪ ⓪%; *** SCC initialisieren ***⓪%;⓪%; Die Clock an RTxCA ist 3.672 MHz, benötigte Baudrate ist 230400 Bit/s.⓪%; Dazu müßte die Clock auf 1/16 geteilt werden.⓪%; Da für Receive DPLL verwendet wird, und DPLL den 16fachen Clk⓪%; braucht, wird trotzdem kein Teiler verwendet. Stattdessen wird⓪%; über den BRG geteilt.⓪%;⓪%; Der SCC arbeitet im Interrupt-Betrieb. Es wird der Non-Auto-Vektor-⓪%; Modus verwendet, auf Adr. $360. Der IR läuft im Level 5.⓪%; Da nur eine einzige IR-Quelle benutzt wird (IR on 1st Rx Char or⓪%; special condition), wird die vector-includes-status-Option nicht⓪%; verwerdet.⓪%;⓪ ⓪(; GIOffBit ($7F);⓪(MOVE.W  #$7F,-(A7)⓪(MOVE    #29,-(A7)⓪(TRAP    #14⓪(ADDQ.L  #4,A7⓪(⓪(MOVE.L  #IR_Handler,IR_Vector⓪(⓪(LEA     SCCInitData,A0⓪(MOVEA.W #CTLA,A1⓪$l1: MOVE.W  (A0)+,D0⓪(BEQ     e1⓪(MOVE.W  D0,D1⓪(LSR     #8,D1⓪(MOVE.B  D1,(A1)⓪(NOP⓪(MOVE.B  D0,(A1)⓪(BRA     l1⓪$e1:⓪(MOVE.B  myAddress,D0⓪(JSR     AcquireAddress⓪(⓪(CLR     deferCount⓪(CLR     collsnCount⓪(CLR     DataFramesOut⓪(CLR     RTSFramesOut⓪(CLR     CTSFramesOut⓪$END⓪"END Init;⓪ ⓪ VAR acqFrame: aTxFrame;⓪ ⓪ PROCEDURE AcquireAddress;⓪"(* IN: D0.B: proposed address, 0 if none *)⓪"BEGIN⓪$ASSEMBLER⓪(; *** choose address ***⓪(BSR     getNewAddress⓪(CLR     fAdrValid⓪(SUBQ    #2,A7⓪&acqlp2:⓪(CLR     fAdrInUse⓪(MOVE.W  #wksTries,(A7)⓪&acqlp:⓪(; TransmitPacket (myAddress, lapENQ, ENQframe.dataField, 0)⓪(LEA     acqFrame,A0⓪(MOVE.B  myAddress,D0⓪(MOVE.B  D0,aTxFrame.ctrl.dstAddr(A0)⓪(MOVE.B  D0,aTxFrame.ctrl.srcAddr(A0)⓪(MOVE.B  #lapENQ,aTxFrame.ctrl.lapType(A0)⓪(CLR.W   aTxFrame.dataCnt(A0)⓪(JSR     TransmitPacket⓪(CMPI    #transmitOK,D0⓪(BEQ     adrIsUsed⓪(TST     fAdrInUse⓪(BEQ     adrNotUsed⓪ adrIsUsed:⓪(MOVEQ   #0,D0⓪(BSR     getNewAddress⓪(BRA     acqlp2⓪ adrNotUsed:⓪(SUBQ    #1,(A7)⓪(BNE     acqlp⓪(ADDQ    #2,A7⓪(MOVE    #1,fAdrValid⓪(RTS⓪ ⓪ getNewAddress:⓪(TST.B   D0⓪(BNE     takeIt⓪(MOVEQ   #127,D0⓪(JSR     random⓪(ADDQ    #1,D0⓪&takeIt:⓪(MOVE.B  D0,myAddress⓪(; setAddress⓪(MOVEA.W #CTLA,A1⓪(MOVE.B  #6,(A1)⓪(MOVE.B  myAddress,(A1)⓪$END;⓪"END AcquireAddress;⓪ ⓪ PROCEDURE TransmitPacket;⓪"(* IN:  A0: ^aTxFrame⓪%OUT: D0.W TransmitStatus *)⓪ ⓪"PROCEDURE BitCount;⓪$BEGIN⓪&ASSEMBLER⓪*; In: D0.B, Out: D1.W /D0-D2/⓪*MOVEQ   #0,D1⓪*MOVEQ   #7,D2⓪'l: LSR.B   #1,D0⓪*BCC     c⓪*ADDQ    #1,D1⓪'c: DBRA    D2,l⓪&END⓪$END BitCount;⓪"⓪"BEGIN (* TransmitPacket *)⓪$ASSEMBLER⓪(TST     fAdrInUse⓪(BEQ     notInUse⓪(MOVEQ   #dupAddress,D0⓪(RTS⓪¬InUse:⓪(MOVE.L  A0,-(A7)⓪(⓪(LEA     RTSframe,A1⓪(MOVE.B  aTxFrame.ctrl.dstAddr(A0),aTxFrame.ctrl.dstAddr(A1)⓪(MOVE.B  myAddress,aTxFrame.ctrl.srcAddr(A1)⓪(MOVE.B  #lapRTS,aTxFrame.ctrl.lapType(A1)⓪(CLR.W   aTxFrame.dataCnt(A1)⓪(⓪(MOVE.B  collsnHistory,D0⓪(BSR     BitCount⓪(CMPI    #2,D1⓪(BLS     c1⓪(⓪(; increase backoff because of too many collisions⓪(CLR.B   collsnHistory⓪(MOVE.W  backoff,D0⓪(BEQ     c2⓪(LSL     #1,D0⓪(CMPI    #16,D0⓪(BLS     c3⓪(MOVEQ   #16,D0⓪(BRA     c3⓪$c2: MOVEQ   #2,D0⓪$c3: MOVE    D0,backoff⓪(⓪$c1: MOVE.B  deferHistory,D0⓪(BSR     BitCount⓪(CMPI    #2,D1⓪(BCC     c4⓪(⓪(; decrease backoff if no defers recently⓪(CLR.B   deferHistory⓪(LSR.W   backoff⓪(⓪$c4: ; shift history data⓪(LSL     collsnHistory⓪(LSL     deferHistory⓪(⓪(CLR.W   deferTries⓪(CLR.W   collsnTries⓪(MOVE.W  backoff,lclbackoff⓪(⓪(MOVEA.W #CTLA,A1⓪(MOVEA.W #$FA00,A2⓪(⓪ again1: ; *** main loop ***⓪(⓪(; *** defer while there are other transmissions in progress ***⓪(⓪(; carrierSense?⓪(BTST    #4,CTLA⓪(BNE.W   noCarrier⓪(⓪(BRA     defer1⓪(⓪&defer2:⓪(ADDQ.W  #1,deferCount⓪(ADDQ.W  #1,deferTries⓪(CMPI.W  #maxDefers,deferTries⓪(BLS     defer1⓪(⓪(; *** Error: too many defers ***⓪(MOVE.W  #excessDefers,D0⓪(BRA.W   exit⓪(⓪&defer1:⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; defer⓪(CMPI    #2,lclbackoff⓪(BCC     c5⓪(MOVE    #2,lclbackoff⓪&c5:⓪(BSET    #0,deferHistory⓪(⓪(; wait for packet to pass⓪(; Delay: maxFrameSize * 1.5 * byteTime (39µs) = maxFrameSize * 58.5 Zyklen⓪(MOVE    #maxFrameSize,D1⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #36,$1F(A2)     ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A2)      ; TACR: Timer Start (Teiler: 1/4)⓪(BRA     c6⓪$l6: BTST    #4,CTLA⓪(BNE     c7              ; kein Carrier mehr⓪(BTST    #5,$0B(A2)⓪(BEQ     c6⓪(MOVE.B  #$DF,$0B(A2)    ; time over: Clear Timer-A Pending Bit⓪$c6: DBRA    D1,l6⓪(⓪(; something is wrong: ResetRx⓪(JSR     resetRx⓪$c7: MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪&noCarrier:⓪(⓪(; resetMissingClock⓪(MOVE.B  #14,(A1)⓪(MOVE.B  #$41,(A1)⓪(⓪(; wait for min. IDG time after packet or idle line⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #minIDGtime DIV 4,$1F(A2)      ; Set Timer Count⓪(MOVE.B  #2,$19(A2)      ; TACR: Timer Start (Teiler: 1/10)⓪$l7: BTST    #4,CTLA⓪(BEQ     defer1          ; erneut Carrier aufgetreten⓪(BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l7⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; wait additional backoff time, deferring to others⓪(MOVE    lclbackoff,D0⓪(JSR     random⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #IDGslottime DIV 4,$1F(A2)      ; Set Timer Count⓪(MOVE.B  #2,$19(A2)      ; TACR: Timer Start (Teiler: 1/10)⓪(BRA     c8⓪$l8: BTST    #4,CTLA⓪(BEQ     defer2          ; erneut Carrier aufgetreten⓪(BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l8⓪(MOVE.B  #$DF,$0B(A2)    ; time over: Clear Timer-A Pending Bit⓪$c8: DBRA    D0,l8⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; missing clock?⓪(MOVE.B  #10,(A1)⓪(TST.B   (A1)            ; RR10⓪(BMI     defer2⓪(⓪(; *** send RTS ***⓪(⓪(MOVE.L  (A7),A0⓪(CMPI.B  #lapENQ,aTxFrame.ctrl.lapType(A0)⓪(BEQ     sndENQ⓪(LEA     RTSframe,A0⓪ sndENQ: MOVE    SR,D2⓪(ORI     #NMI_Mask,SR⓪(ADDQ.W  #1,RTSFramesOut⓪(JSR     TransmitFrame⓪(⓪(; enableRx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #rxEnable,(A1)⓪(⓪(MOVE    #1,fCTSexpected⓪(MOVE    D2,SR⓪(; *** wait for CTS ***⓪(SUBQ.L  #4,A7⓪(MOVE.L  A7,(A3)+⓪(MOVEM.L A1/A2,-(A7)⓪(JSR     ReceiveFrame/⓪(MOVEM.L (A7)+,A1/A2⓪(ADDQ.L  #4,A7⓪(CLR     fCTSexpected⓪(⓪(TST     fAdrInUse⓪(BEQ     noDup⓪(⓪(; *** Error: duplicate address ***⓪(MOVE.W  #dupAddress,D0⓪(BRA.W   exit⓪(⓪ noDup:  MOVE.L  (A7),A0⓪(CMPI.B  #$FF,aTxFrame.ctrl.dstAddr(A0)⓪(BNE     chkCTS⓪(; broadcast-Transmit auswerten⓪(CMPI    #noFrame,D0⓪(BNE     error1⓪(BRA     send2⓪ chkCTS: CMPI    #lapCTSframe,D0⓪(BNE     error1⓪(CMPI.B  #lapENQ,aTxFrame.ctrl.lapType(A0)⓪(BEQ     error1⓪(⓪ send2:  ; *** eigentliches Paket senden ***⓪(MOVE    SR,D2⓪(ORI     #NMI_Mask,SR⓪(ADDQ.W  #1,DataFramesOut⓪(JSR     TransmitFrame⓪(⓪(; enableRx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #rxEnable,(A1)⓪(⓪(MOVE    D2,SR⓪(MOVE.W  #transmitOK,D0⓪(BRA.W   exit⓪(⓪ error1  ; assume collision because we didn't receive the expected CTS⓪(ADDQ    #1,collsnCount⓪(BSET    #0,collsnHistory⓪(ADDQ    #1,collsnTries⓪(CMPI    #maxCollsns,collsnTries⓪(BHI     excssC⓪(⓪(MOVE.W  lclbackoff,D0⓪(BEQ     c12⓪(LSL     #1,D0⓪(CMPI    #16,D0⓪(BLS     c13⓪(MOVEQ   #16,D0⓪(BRA     c13⓪#c12: MOVEQ   #2,D0⓪#c13: MOVE    D0,lclbackoff⓪(⓪(BRA     again1⓪(⓪ excssC: ; *** Error: too many collisions ***⓪(MOVE.W  #excessCollsns,D0⓪ exit:   ADDQ.L  #4,A7⓪$END;⓪"END TransmitPacket;⓪ ⓪ PROCEDURE TransmitFrame;⓪"BEGIN⓪$ASSEMBLER⓪(; A0: ^aTxFrame, A1: CTLA, A2: $FFFFFA00⓪(; enableTxDrivers⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #setRTS,(A1)⓪(⓪(; Pause f. Sync-Pulse (1 Bit: 1.5 * bitTime (6.51µs) = 16 Zyklen)⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #4,$1F(A2)      ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A2)      ; TACR: Timer Start (Teiler: 1/4)⓪%l: BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; disableTxDrivers⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #$60,(A1)⓪(⓪(; Pause f. Sync-Pulse (1 Bit: 1.5 * bitTime (6.51µs) = 16 Zyklen)⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #4,$1F(A2)      ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A2)      ; TACR: Timer Start (Teiler: 1/4)⓪%l2 BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l2⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; enableTxDrivers, enableTx⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #txEnable,(A1)⓪(⓪(; disableRx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #$D0,(A1)⓪(⓪(; 2 * txFlag⓪(; Delay: 2 * 1.5 * byteTime (39µs) = 116 Zyklen⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #70,$1F(A2)     ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A2)      ; TACR: Timer Start (Teiler: 1/4)⓪%l3 BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l3⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; resetCRC⓪(MOVE.B  #$80,(A1)⓪(⓪(BSR     TxChar⓪(BSR     TxChar⓪(BSR     TxChar⓪(ADDQ.L  #1,A0⓪(MOVE.W  (A0)+,D0⓪(DBRA    D0,nextChar2⓪(BRA     allSent⓪%nextChar2:⓪(MOVE.L  (A0)+,A0⓪%nextChar:⓪(BTST    #2,(A1)⓪(BEQ     nextChar⓪(MOVE.B  (A0)+,2(A1)⓪(DBRA    D0,nextChar⓪%allSent:⓪(⓪(; resetUnderrun⓪(MOVE.B  #$C0,(A1)⓪(⓪(; TxFCS: wait for underrun⓪%notUnder:⓪(BTST    #6,(A1)⓪(BEQ     notUnder⓪(⓪(; TxFlag (?)⓪%notEmpty2:⓪(BTST    #2,(A1)⓪(BEQ     notEmpty2⓪(⓪(; enableTxDrivers, disableTx⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #setRTS,(A1)⓪(⓪(; txONEs (?)⓪(; Delay: 1.5 * byteTime (39µs) = 58 Zyklen⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #35,$1F(A2)     ; TADR: Set Timer Count⓪(MOVE.B  #1,$19(A2)      ; TACR: Timer Start (Teiler: 1/4)⓪%l4 BTST    #5,$0B(A2)      ; IPRA⓪(BEQ     l4⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(⓪(; disableTxDrivers⓪(MOVE.B  #5,(A1)⓪(MOVE.B  #$60,(A1)⓪(⓪(; resetMissingClock⓪(MOVE.B  #14,(A1)⓪(MOVE.B  #$41,(A1)⓪(RTS⓪(⓪%TxChar:⓪(BTST    #2,(A1)⓪(BEQ     TxChar⓪(MOVE.B  (A0)+,2(A1)⓪$END;⓪"END TransmitFrame;⓪ ⓪ (*$L+*)⓪ ⓪ PROCEDURE ReceivePacket (VAR dstParam: anAddress;⓪9VAR srcParam: anAddress;⓪9VAR typeParam: aLAPtype;⓪9VAR dataParam: aDataField;⓪9VAR dataLength: INTEGER);⓪"VAR status: ReceiveStatus; packet: ptrPacket;⓪"BEGIN⓪$REPEAT UNTIL (ReceiveLinkMgmt (packet) = receiveOK) OR InOut.KeyPressed ();⓪$WITH packet^.frame DO⓪&dstParam:= dstAddr;⓪&srcParam:= srcAddr;⓪&typeParam:= lapType;⓪&dataParam:= dataField (*!!! hier werden 600 Byte kopiert -> Ptr verw.*)⓪$END;⓪"END ReceivePacket;⓪ ⓪ PROCEDURE ReceiveLinkMgmt (VAR packet: ptrPacket): ReceiveStatus;⓪"⓪"VAR status: ReceiveStatus;⓪&rcvdStatus: FrameStatus;⓪&sr: CARDINAL;⓪"⓪"BEGIN⓪$ASSEMBLER⓪(MOVE    SR,sr(A6)⓪(MOVE    #$2500,SR⓪$END;⓪$status:= receiving;⓪$REPEAT⓪&rcvdStatus:= ReceiveFrame (packet);⓪&IF rcvdStatus # noFrame THEN⓪(InOut.WriteCard (packet^.no, 1); InOut.Write (' ');⓪(WriteFrame (packet^,99);⓪(InOut.WriteLn;⓪(WriteStatus (rcvdStatus); InOut.WriteLn;⓪&END;⓪&CASE rcvdStatus OF⓪&|badframeCRC, badframeSize, badframeType, overrunError, underrunError,⓪'lostAddress:⓪(status:= frameError⓪&|lapACKframe:⓪&|lapENQframe:⓪((* wird nun schon beim Empfang erledigt *)⓪(HALT⓪((*⓪*IF fAdrValid THEN⓪,WITH ACKframe DO⓪.dstAddr:= packet^.frame.srcAddr;⓪.srcAddr:= myAddress;⓪.lapType:= lapACK⓪,END;⓪,TransmitFrame (ACKframe, 3);⓪*ELSE⓪,fAdrInUse:= TRUE⓪*END;⓪*status:= nullReceive⓪(*)⓪&|lapRTSframe:⓪((* wird nun schon beim Empfang erledigt *)⓪(HALT⓪((*⓪*IF fAdrValid THEN⓪,WITH CTSframe DO⓪.dstAddr:= headPacket^.frame.srcAddr;⓪.srcAddr:= myAddress;⓪.lapType:= lapCTS⓪,END;⓪,TransmitFrame (CTSframe, 3);⓪*ELSE⓪,fAdrInUse:= TRUE;⓪,status:= nullReceive⓪*END;⓪(*)⓪&|lapDATAframe:⓪(IF fAdrValid THEN⓪*status:= receiveOK⓪(ELSE⓪*ASSEMBLER⓪+;BREAK⓪*END;⓪*fAdrInUse:= TRUE;⓪*status:= nullReceive⓪(END;⓪&|noFrame:⓪(status:= nullReceive⓪&ELSE⓪&END⓪$UNTIL status # receiving;⓪$ASSEMBLER⓪(MOVE    sr(A6),SR⓪$END;⓪$RETURN status⓪"END ReceiveLinkMgmt;⓪ ⓪ PROCEDURE ReceiveFrame (VAR packet: ptrPacket): FrameStatus;⓪"⓪"VAR status: FrameStatus;⓪ ⓪"BEGIN⓪$ASSEMBLER⓪(MOVEA.W #CTLA,A1⓪(MOVEA.W #$FA00,A2⓪(MOVE.L  tailPacket,A0⓪(⓪(; *** warten auf Frame-Empfang (IR o. Polling) ***⓪(⓪(MOVEQ   #0,D1⓪(⓪$l1: MOVE.B  #$DF,$0B(A2)               ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  #maxIFGtime DIV 4,$1F(A2)  ; TADR: Set Timer Count⓪(MOVE.B  #2,$19(A2)                 ; TACR: Timer Start (Teiler: 1/10)⓪$l0: ; zuerst prüfen, ob evtl. noch ein Frame zu pollen ist,⓪(; auch wenn noch weitere Pakete schon im Puffer warten.⓪(MOVE.B  #3,(A1)⓪(BTST.B  #5,(A1)         ; RR3: Rx IR pending?⓪(BNE     pollFrame⓪(CMPA.L  headPacket,A0⓪(BNE     gotFrame⓪(BTST    #5,$0B(A2)      ; time over?⓪(BEQ     l0⓪(; IR-Receive nochmal prüfen, falls IR zw. vorigem CMP und Time-Chk kam.⓪(CMPA.L  headPacket,A0⓪(BNE     gotFrame⓪(⓪((*⓪(TST     test⓪(BEQ     timeout⓪(⓪(ADDQ    #1,D1⓪(BRA     l1⓪(*)⓪(⓪$timeout:⓪(; time out⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(MOVE.L  packet(A6),A0⓪(CLR.L   (A0)⓪(MOVE    #noFrame,status(A6)⓪(BRA.W   exit2⓪(⓪$gotFrame:⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(BRA     exit⓪(⓪$pollFrame:⓪(MOVE    SR,D2⓪(ORI     #NMI_Mask,SR⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪(JSR     GetFrame⓪(MOVE.B  #1,(A1)⓪(MOVE.B  #$08,(A1)⓪(MOVE    D2,SR⓪(⓪$exit:⓪(MOVE.L  tailPacket,D0⓪(MOVE.L  packet(A6),A0⓪(MOVE.L  D0,(A0)⓪(MOVE.L  D0,A0⓪(MOVE    aPacket.status(A0),status(A6)⓪(MOVE.L  aPacket.next(A0),tailPacket⓪(⓪$exit2:⓪$END;⓪$RETURN status ⓪"END ReceiveFrame;⓪ ⓪ PROCEDURE IR_Handler;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(ORI     #NMI_Mask,SR⓪(MOVEM.L A0-A2/D0-D1,-(A7)⓪(⓪(MOVEA.W #$FA00,A2⓪(MOVEA.W #CTLA,A1⓪(JSR     GetFrame⓪(⓪(ADDQ.W  #1,Interrupts⓪(⓪(MOVEM.L (A7)+,A0-A2/D0-D1⓪(RTE⓪$END;⓪"END IR_Handler;⓪"(*$L=*)⓪ ⓪ PROCEDURE GetFrame;⓪"(*$L-*)⓪"BEGIN⓪$ASSEMBLER⓪(; overrun?⓪(MOVE.B  #1,(A1)   ; RR1⓪(BTST.B  #5,(A1)⓪(BNE     isOverrun⓪(⓪(MOVE.L  headPacket,A0⓪(⓪(MOVE.B  2(A1),D0                ; 1. char sofort holen⓪(MOVE.B  D0,aPacket.frame(A0)⓪(⓪(MOVE.B  #2,4(A1)⓪(BTST.B  #0,4(A1)                ; RR2B⓪(BNE     specCond⓪(⓪(MOVEQ   #100,D1⓪&wait2:⓪(BTST    #0,(A1)⓪(DBNE    D1,wait2⓪(; overrun?⓪(MOVE.B  #1,(A1)   ; RR1⓪(BTST.B  #5,(A1)⓪(BNE     isOverrun⓪(⓪(MOVE.B  2(A1),aPacket.frame+1(A0)⓪(⓪(MOVEQ   #2,D0⓪(BRA     nextChar⓪(⓪$specCond:⓪(⓪$again:⓪(CLR     D0⓪(⓪$loop2:⓪(; overrun?⓪(MOVE.B  #1,(A1)   ; RR1⓪(BTST.B  #5,(A1)⓪(BEQ     noOverrun⓪(⓪$isOverrun:⓪(MOVE    D0,aPacket.length(A0)⓪(MOVE.W  #overrunError,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪$timeOut:⓪(MOVE    D0,aPacket.length(A0)⓪(MOVE.W  #noFrame,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪$noOverrun:⓪(MOVEQ   #100,D1 ;!!! Wert OK?⓪&wait4:⓪(BTST    #0,(A1)⓪(DBNE    D1,wait4⓪(BEQ     timeOut⓪(⓪(; *** read data ***⓪(CMPI.W  #maxFrameSize,D0        ; incomingLength⓪(BCS     getChar⓪(⓪$sizeError:⓪(MOVE    D0,aPacket.length(A0)⓪(MOVE.W  #badframeSize,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪$getChar:⓪(; headPacket^.frame.rawData [incomingLength]:= rxData ()⓪(MOVE.B  2(A1),aPacket.frame(A0,D0.W)  ; RR8⓪(ADDQ.W  #1,D0             ; incomingLength⓪(⓪$nextChar:⓪$noDataNow:⓪(; end of frame?⓪(MOVE.B  #1,(A1)   ; RR1⓪(TST.B   (A1)⓪(BPL     loop2⓪(⓪(SUBQ.W  #2,D0           ; incomingLength⓪(MOVE    D0,aPacket.length(A0)⓪(⓪(CMPI.W  #minFrameSize,D0⓪(BCS     sizeError⓪(⓪(; resetRx⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #$D0,(A1)       ; disableRx⓪(⓪(; CRC OK?⓪(MOVE.B  #1,(A1)   ; RR1⓪(BTST.B  #6,(A1)⓪(BEQ     crcOK⓪(⓪(MOVE.W  #badframeCRC,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪$crcOK:⓪(; Stimmt 1. Byte (unsere Adr. oder #$FF)?⓪(MOVE.B  aPacket.frame(A0),D0⓪(CMPI.B  #$FF,D0⓪(BEQ     adrOK⓪(CMP.B   myAddress,D0⓪(BEQ     adrOK⓪(⓪(MOVE.W  #lostAddress,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪%adrOK:⓪(; *** frameDone ***⓪(⓪(TST.W   fAdrValid⓪(BEQ     notValid⓪(⓪(MOVE.B  aPacket.frame.lapType(A0),D0⓪(BMI     ctrlFrame⓪(⓪(MOVE.W  #lapDATAframe,aPacket.status(A0)⓪(BRA.W   exit2⓪(⓪&ctrlFrame:⓪(CMPI.B  #lapENQ,D0⓪(BEQ     isENQ⓪(CMPI.B  #lapACK,D0⓪(BEQ     isACK⓪(CMPI.B  #lapRTS,D0⓪(BEQ     isRTS⓪(CMPI.B  #lapCTS,D0⓪(BEQ     isCTS⓪&badFrame:⓪(MOVE.W  #badframeType,aPacket.status(A0)⓪(BRA     exit2⓪&isENQ:⓪(MOVE.W  #lapENQframe,aPacket.status(A0)⓪(⓪(BRA     exit2⓪&isACK:⓪(MOVE.W  #lapACKframe,aPacket.status(A0)⓪(MOVE.W  #1,fAdrInUse⓪(BRA     exit2⓪&isRTS:⓪(MOVE.W  #lapRTSframe,aPacket.status(A0)⓪(BRA     exit2⓪&isCTS:⓪(MOVE.W  #lapCTSframe,aPacket.status(A0)⓪(TST.W   fCTSexpected⓪(BNE     exit2⓪(; das muß wieder hier rein (s. NOTES):⓪(MOVE.W  #1,fAdrInUse⓪(BRA     badFrame⓪(BRA     isNoFrame ;!!!testweise⓪(⓪¬Valid:⓪(CMPI.B  #$FF,aPacket.frame.dstAddr(A0)⓪(BEQ     exit2⓪(⓪(;BREAK⓪(MOVE    #1,fAdrInUse⓪&isNoFrame⓪(MOVE.W  #noFrame,aPacket.status(A0)⓪(⓪$exit2:⓪(⓪(MOVEQ   #2,D0⓪&flushFIFO:⓪(TST.B   2(A1)⓪(DBRA    D0,flushFIFO⓪(⓪(; resetMissingClock⓪(;MOVE.B  #14,(A1)⓪(;MOVE.B  #$41,(A1)⓪(⓪(; reset error⓪(MOVE.B  #$30,(A1)⓪(⓪(; reset IUS⓪(MOVE.B  #$38,(A1)⓪(⓪(; resetMissingClock⓪(MOVE.B  #14,(A1)⓪(MOVE.B  #$41,(A1)⓪(⓪(⓪(CMPI.W  #lapENQframe,aPacket.status(A0)⓪(BNE     noENQ⓪(⓪(; ACK senden⓪(⓪(CLR.W   -(A7)⓪(MOVE.B  #lapACK,-(A7)⓪(BRA     sendCtrlFrame⓪(⓪&noENQ:⓪(⓪(CMPI.W  #lapRTSframe,aPacket.status(A0)⓪(BNE     noRTS⓪(⓪(; CTS senden, falls kein Broadcast⓪(⓪(CMPI.B  #$FF,aPacket.frame.dstAddr(A0)⓪(BEQ     noCTS⓪(CLR.W   -(A7)⓪(MOVE.B  #lapCTS,-(A7)⓪&sendCtrlFrame:⓪(MOVE.B  aPacket.frame.srcAddr(A0),D0⓪(LSL     #8,D0⓪(MOVE.B  myAddress,D0⓪(MOVE.W  D0,-(A7)⓪(MOVE.L  A7,A0⓪(ADDQ.W  #1,CTSFramesOut⓪(JSR     TransmitFrame⓪(ADDQ.L  #6,A7⓪(MOVE.L  headPacket,A0⓪&noCTS:⓪(MOVE.W  #noFrame,aPacket.status(A0)⓪(⓪&noRTS:⓪(⓪(ADDQ.W  #1,FramesReceived⓪(⓪(MOVE.L  aPacket.next(A0),A0⓪(MOVE.L  A0,headPacket⓪(⓪(MOVE.B  #$20,(A1)         ; enable IR on next Rx⓪(⓪(MOVE.B  #3,(A1)⓪(MOVE.B  #rxEnable,(A1)  ; enableRx⓪(⓪(; more IRs?⓪(BTST    #0,(A1)⓪(BNE     again⓪$END⓪"END GetFrame;⓪"(*$L=*)⓪ ⓪ BEGIN⓪"packetBuffers:= 0;⓪ END (* MODULE *) ALAP;⓪ ⓪ (*****************************************************************************)⓪ ⓪ TYPE BS = SET OF [0..7];⓪%RegSet = SET OF [0..15];⓪ ⓪ CONST ReadRegs  = RegSet {0,1,2,3,8,10,12,13,15};⓪&WriteRegs = RegSet {0..15};⓪&⓪&RegsToDisplay = RegSet {0,1,2,3,8,10,12,13,15};⓪&⓪ ⓪ PROCEDURE WriteReg (n: CARDINAL);⓪"VAR reg: CARDINAL;⓪"BEGIN⓪$reg:= SCC.Reg (n);⓪$WriteNum (reg, 16, 2, '0');⓪$WriteString ('  ');⓪$WriteNum (reg, 2, 8, '0');⓪"END WriteReg;⓪ ⓪ ⓪ VAR ch: CHAR;⓪$rxIdx, n, c: CARDINAL;⓪$lc: LONGCARD;⓪$i: INTEGER;⓪$ssp, li: LONGINT;⓪$redraw, quit, ok, b: BOOLEAN;⓪$by: BS;⓪$myaddr, outaddr: CARDINAL;⓪$sentDatas,sendTrials,rcvdDatas: LONGCARD;⓪$⓪$txFrame: ALAP.aTxFrame;⓪$packet: ALAP.ptrPacket;⓪$dstParam, srcParam: ALAP.anAddress;⓪$typeParam: ALAP.aLAPtype;⓪$dataParam: ALAP.aDataField;⓪$txStatus: ALAP.TransmitStatus;⓪$frameStatus: ALAP.FrameStatus;⓪$dataLength: INTEGER;⓪ ⓪ BEGIN⓪"WritePg;⓪"ssp:= Super (0);⓪"⓪"(*⓪"WriteLn;⓪"WriteString ('Start...');⓪"FOR c:= 1 TO 5 DO⓪$FOR n:= 1 TO 5*1000 DO⓪&ASSEMBLER⓪(MOVEA.W #$FA00,A2⓪(MOVEQ   #50,D0⓪(MOVE.B  #$DF,$0B(A2)    ; IPRA: Clear Timer-A Pending Bit⓪(MOVE.B  D0,$1F(A2)      ; TADR: Set Timer Count⓪(MOVE.B  #2,$19(A2)      ; TACR: Timer Start (Teiler: 1/10)⓪$l0: BTST    #5,$0B(A2)      ; time over?⓪(BEQ     l0⓪(MOVE.B  #$00,$19(A2)    ; TACR: Timer Stop⓪&END;⓪$END;⓪"END;⓪"WriteString ('Stop!');⓪"WriteLn;⓪"*)⓪"⓪"WriteLn;⓪"WriteString ('Init...');⓪"WriteLn;⓪"⓪"ASSEMBLER⓪(MOVEQ   #0,D0⓪(JSR     ALAP.Init;⓪"END;⓪"⓪"ALAP.NewPacketBuffer;⓪"ALAP.NewPacketBuffer;⓪"ALAP.NewPacketBuffer;⓪"ALAP.NewPacketBuffer;⓪"⓪"WriteString ('OK');⓪"WriteLn;⓪"⓪"rxIdx:= 0;⓪"redraw:= TRUE;⓪"quit:= FALSE;⓪"REPEAT⓪$IF redraw THEN⓪&GotoXY (4,0);⓪&WriteString (' interrupts');⓪&GotoXY (4,1);⓪&WriteString (' frames received');⓪&GotoXY (0,2);⓪&FOR n:= 0 TO 15 DO⓪(IF n IN ReadRegs THEN⓪*WriteString ('Reg '); WriteNum (n, 16, 1, '0'); WriteString (': '); WriteLn;⓪(END⓪&END;⓪&WriteString (VT52.Seq[clearEOS]);⓪&⓪&c:= 2;⓪&FOR n:= 0 TO 15 DO⓪(IF n IN ReadRegs THEN⓪*IF n IN RegsToDisplay THEN GotoXY (7,c); WriteReg (n) END;⓪*INC (c);⓪(END;⓪&END;⓪&⓪&GotoXY (0, 11);⓪&WriteString ('myAddress: '); WriteHex (LONG (ALAP.myAddress), 3);⓪&WriteString (', dest-Addr: '); WriteHex (outaddr, 3);⓪&GotoXY (0, 12);⓪&WriteString ('collsns:   , defers:');⓪&GotoXY (0, 13);⓪&WriteString ('RTS:   , CTS:   , Data:');⓪&redraw:= FALSE⓪$END;⓪$GotoXY (0,0);⓪$WriteCard (ALAP.Interrupts, 4);⓪$GotoXY (0,1);⓪$WriteCard (ALAP.FramesReceived, 4);⓪$GotoXY (8,12);⓪$WriteCard (ALAP.collsnCount,3);⓪$GotoXY (20,12);⓪$WriteCard (ALAP.deferCount,3);⓪$GotoXY (4,13);⓪$WriteCard (ALAP.RTSFramesOut,3);⓪$GotoXY (13,13);⓪$WriteCard (ALAP.CTSFramesOut,3);⓪$GotoXY (23,13);⓪$WriteCard (ALAP.DataFramesOut,3);⓪$⓪$ASSEMBLER MOVE SR,-(A7) ORI.W #$0700,SR END;⓪$IF ALAP.headPacket # ALAP.tailPacket THEN⓪&frameStatus:= ALAP.ReceiveFrame (packet);⓪&GotoXY (40, rxIdx);⓪&WriteCard (rxIdx, 2);⓪&INC (rxIdx);⓪&WriteString (': ');⓪&ALAP.WriteFrame (packet^, 5);⓪&InOut.WriteCard (packet^.no, 1); InOut.Write (' ');⓪&ALAP.WriteStatus (packet^.status);⓪$END;⓪$ASSEMBLER MOVE.W (A7)+,SR END;⓪$⓪$IF KeyPressed() THEN⓪&GotoXY (0,14);⓪&WriteString (VT52.Seq[clearEOS]);⓪&WriteLn;⓪&Read (ch); ch:= CAP (ch);⓪&IF ch = 'Q' THEN⓪(quit:= TRUE;⓪&ELSIF ch = 'T' THEN⓪(WriteLn;⓪(WriteString ('Transmitting...');⓪(WriteLn;⓪(⓪((*txStatus:= ALAP.TransmitPacket (outaddr, BYTE($10), dataParam, 0);*)⓪(WITH txFrame DO⓪*ctrl.srcAddr:= ALAP.myAddress;⓪*ctrl.dstAddr:= SHORT (outaddr);⓪*ctrl.lapType:= BYTE ($10);⓪*dataCnt:= 2;⓪*dataPtr:= ADR (dataParam);⓪*dataParam[1]:= BYTE ($12);⓪*dataParam[2]:= BYTE ($34);⓪(END;⓪(ASSEMBLER⓪*LEA   txFrame,A0⓪*JSR   ALAP.TransmitPacket⓪*MOVE  D0,txStatus⓪(END;⓪(⓪(ALAP.fAdrInUse:= FALSE;⓪(WriteString ('Status: ');⓪(CASE txStatus OF⓪(| ALAP.transmitOK: WriteString ('transmitOK')⓪(| ALAP.excessDefers: WriteString ('excessDefers')⓪(| ALAP.excessCollsns: WriteString ('excessCollsns')⓪(| ALAP.dupAddress: WriteString ('dupAddress')⓪(END;⓪(WriteLn;⓪&ELSIF ch = 'R' THEN⓪(WriteLn;⓪(WriteString ('Receiving...');⓪(WriteLn;⓪(ALAP.ReceivePacket (dstParam, srcParam, typeParam, dataParam, dataLength);⓪(IF InOut.KeyPressed () THEN⓪*WriteString ('Aborted');⓪*Read (ch)⓪(ELSE⓪*WriteString ('OK');⓪(END⓪&ELSIF ch = 'G' THEN⓪(WriteLn;⓪(WriteString ('Getting Addresses on Bus...');⓪(WriteLn;⓪(FOR n:= $01 TO $7F DO⓪*⓪*(*txStatus:= ALAP.TransmitPacket (SHORT(n), BYTE($81), dataParam, 0);*)⓪*WITH txFrame DO⓪,ctrl.srcAddr:= ALAP.myAddress;⓪,ctrl.dstAddr:= SHORT (n);⓪,ctrl.lapType:= ALAP.lapENQ;⓪,dataCnt:= 0⓪*END;⓪*ASSEMBLER⓪,LEA   txFrame,A0⓪,JSR   ALAP.TransmitPacket⓪,MOVE  D0,txStatus⓪*END;⓪*⓪*IF txStatus = ALAP.dupAddress THEN⓪,Write ('>'); WriteHex (n, 3); Write ('<'); WriteLn;⓪*END;⓪*ALAP.fAdrInUse:= FALSE;⓪(END;⓪(WriteLn;⓪(WriteString ('OK.');⓪(WriteLn;⓪&ELSIF ch = ' ' THEN⓪(WritePg;⓪(rxIdx:= 0;⓪(redraw:= TRUE⓪&ELSIF ch = 'I' THEN⓪(WriteString ('Address? ');⓪(ReadCard (myaddr);⓪(IF Done THEN⓪*ASSEMBLER⓪,MOVE  myaddr,D0⓪,JSR   ALAP.Init⓪*END⓪(END⓪&ELSIF ch = 'A' THEN⓪(WriteString ('Dest-Address? ');⓪(ReadCard (outaddr);⓪&ELSIF ch = '0' THEN⓪((*⓪*Test-Modus.⓪*sieht NUR mit Polling nach, ob Daten angekommen sind.⓪(*)⓪(rcvdDatas:= 0;⓪(ASSEMBLER MOVE SR,-(A7) ORI.W #$0500,SR END;⓪(LOOP⓪*frameStatus:= ALAP.ReceiveFrame (packet);⓪*IF frameStatus = ALAP.lapDATAframe THEN⓪,INC (rcvdDatas);⓪,WriteHex (LONG(packet^.frame.srcAddr),3);⓪,IF packet^.frame.lapType = BYTE ($11) THEN EXIT END;⓪*END;⓪(END;⓪(ASSEMBLER MOVE.W (A7)+,SR END;⓪(WriteLn;⓪(WriteCard (rcvdDatas,0); WriteString (' frames received');⓪(Read (ch);⓪&ELSIF ch = '1' THEN⓪((*⓪*Test-Modus.⓪*sieht mit Polling nach, ob Daten angekommen sind.⓪(*)⓪(rcvdDatas:= 0;⓪(LOOP⓪*frameStatus:= ALAP.ReceiveFrame (packet);⓪*IF frameStatus = ALAP.lapDATAframe THEN⓪,INC (rcvdDatas);⓪,WriteHex (LONG(packet^.frame.srcAddr),3);⓪,IF packet^.frame.lapType = BYTE ($11) THEN EXIT END;⓪*END;⓪*IF KeyPressed() THEN EXIT END;⓪(END;⓪(WriteLn;⓪(WriteCard (rcvdDatas,0); WriteString (' frames received');⓪(Read (ch);⓪&ELSIF ch = '2' THEN⓪((*⓪*Test-Modus.⓪*sieht NUR im Interrupt nach, ob Daten angekommen sind.⓪(*)⓪(rcvdDatas:= 0;⓪(LOOP⓪*ASSEMBLER MOVE SR,-(A7) ORI.W #$0700,SR END;⓪*WHILE ALAP.headPacket # ALAP.tailPacket DO⓪,frameStatus:= ALAP.ReceiveFrame (packet);⓪,IF frameStatus = ALAP.lapDATAframe THEN⓪.INC (rcvdDatas);⓪.WriteHex (LONG(packet^.frame.srcAddr),3);⓪.IF packet^.frame.lapType = BYTE ($11) THEN⓪0ASSEMBLER MOVE.W (A7)+,SR END;⓪0EXIT⓪.END;⓪,END;⓪*END;⓪*ASSEMBLER MOVE.W (A7)+,SR END;⓪*IF KeyPressed() THEN EXIT END;⓪(END;⓪(WriteLn;⓪(WriteCard (rcvdDatas,0); WriteString (' frames received');⓪(Read (ch);⓪&ELSIF ch = '3' THEN⓪((*⓪*Test-Modus.⓪*Jede Station sendet ununterbrochen;⓪*sieht jedesmal nach, ob Daten angekommen sind.⓪(*)⓪(rcvdDatas:= 0;⓪(sentDatas:= 0;⓪(sendTrials:= 0;⓪(WITH txFrame DO⓪*ctrl.srcAddr:= ALAP.myAddress;⓪*ctrl.dstAddr:= SHORT (outaddr);⓪*ctrl.lapType:= BYTE ($10);⓪*dataCnt:= 3;⓪*dataPtr:= ADR (dataParam);⓪*dataParam[1]:= BYTE ($12);⓪*dataParam[2]:= BYTE ($34);⓪*dataParam[3]:= BYTE ($56);⓪(END;⓪(LOOP⓪*ASSEMBLER LEA txFrame,A0 JSR ALAP.TransmitPacket MOVE D0,txStatus END;⓪*INC (sendTrials);⓪*IF ALAP.fAdrInUse THEN Write ('#'); ALAP.fAdrInUse:= FALSE; END;⓪*CASE txStatus OF⓪*| ALAP.transmitOK: Write ('.'); INC (sentDatas)⓪*| ALAP.excessDefers: Write ('+')⓪*| ALAP.excessCollsns: Write ('-')⓪*| ALAP.dupAddress:⓪*END;⓪*ASSEMBLER MOVE SR,-(A7) ORI.W #$0700,SR END;⓪*WHILE ALAP.headPacket # ALAP.tailPacket DO⓪,frameStatus:= ALAP.ReceiveFrame (packet);⓪,IF frameStatus = ALAP.lapDATAframe THEN⓪.INC (rcvdDatas);⓪.WriteHex (LONG(packet^.frame.srcAddr),3);⓪.IF packet^.frame.lapType = BYTE ($11) THEN EXIT END;⓪,END;⓪*END;⓪*ASSEMBLER MOVE.W (A7)+,SR END;⓪*IF KeyPressed() THEN EXIT END;⓪(END;⓪(WriteLn;⓪(WriteCard (sendTrials,0); WriteString (' frames tried to sent, ');⓪(WriteCard (sentDatas,0); WriteString (' frames sent, ');⓪(WriteCard (rcvdDatas,0); WriteString (' frames received');⓪(Read (ch);⓪&ELSIF ch = '4' THEN⓪((*⓪*Send Abort to all (Broadcast)⓪(*)⓪(WITH txFrame DO⓪*ctrl.srcAddr:= ALAP.myAddress;⓪*ctrl.dstAddr:= BYTE ($FF);⓪*ctrl.lapType:= BYTE ($11);⓪*dataCnt:= 0;⓪(END;⓪(ASSEMBLER LEA txFrame,A0 JSR ALAP.TransmitPacket MOVE D0,txStatus END;⓪&(*⓪&ELSIF (ch >= '0') & (ch <= '9') OR (ch >= 'A') & (ch <= 'F') THEN⓪(Write (10C); (* BS *)⓪(n:= ORD (ch) - ORD ('0'); IF n > 9 THEN DEC (n, 7) END;⓪(IF n IN WriteRegs THEN⓪*WriteString ('Write Reg '); WriteNum (n, 16, 1, '0');⓪*WriteString ('? ');⓪*ReadCard (c);⓪*IF Done & (c <= 255) THEN⓪,SCC.SetReg (n, c);⓪*ELSE⓪,WriteString ('No write!'); WriteLn⓪*END⓪(END⓪&*)⓪&END;⓪$END;⓪"UNTIL quit;⓪"ssp:= Super (ssp)⓪ END LANMonitor.⓪ ə
  2. (* $FFF006F0$0000432B$00003D8D$FFF006F0$0000692A$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$00008928$FFF006F0$00002C6C$FFF006F0$00000DC7$FFF006F0$00006E39$FFF006F0$00005DAA$00005CA8$00002600$00005833$FFF006F0$FFF006F0$FFF006F0$FFF006F0$FFF006F0$00003185$FFF006F0$00004EAE$FFF006F0$0000451D$FFF006F0$000013E6$00001C5B$FFF006F0$FFF006F0Ç$00008854T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$FFF006F0$FFF006F0$00008FC0$FFF006F0$00008493$0000845F$00008660$000088B0$00008D88$0000849D$000088BE$000088A2$00008881$00008854$0000527C$0000656AÇüé*)
  3.